home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************
- *
- * BSYNZ Version 49
- *
- ******************************************************************
- *
- * Synthesize One Pitch Epoch
- *
- * Inputs:
- * COEF - Predictor coefficients
- * IP - Pitch period (number of samples to synthesize)
- * IV - Voicing for the current epoch
- * RMS - Energy for the current epoch
- * ORDER - Synthesizer filter order (number of PC's)
- * RATIO - Energy slope for plosives
- * G2PASS- Sharpening factor for 2 pass synthesis
- * Outputs:
- * SOUT - Synthesized speech
- */
-
- #include "config.ch"
- /*#include "common.h"*/
- #include "lpcdefs.h"
- #include <math.h>
-
- /*
- #define MESCL 1.0
- #define PESCL 1.0
- */
- float kexc[25]={
- 8,-16,26,-48,86,-162,294,-502,718,-728,
- 184,672,-610,-672,184,728,718,502,294,162,
- 86,48,26,16,8
- };
-
- extern float exc[MAXPIT+MAXORD], exc2[MAXPIT+MAXORD];
-
- bsynz( coef, ip, iv, sout, rms, ratio, g2pass )
- int ip, iv;
- float coef[], sout[], g2pass, rms, ratio;
- {
- int px;
- static int ipo=0;
- int i, j, k;
- float noise[MAXPIT+MAXORD];
- float lpi0, hpi0;
- float a0=.125, a1=.75, a2=.125/*, a3=0*/, b0=-.125, b1=.25, b2=-.125/*, b3=0*/;
- float pulse, sscale, xssq, sum, ssq, gain;
- float xy;
- static float rmso=0.0, lpi1=0.0, lpi2=0.0, /*lpi3,*/ hpi1=0.0, hpi2=0.0/*, hpi3*/;
-
-
- /* Calculate history scale factor XY and scale filter state */
-
- xy = mmin((rmso/(rms+.000001)), 8.0);
- rmso = rms;
- for(i=0;i<ORDER;i++)
- exc2[i] = exc2[ipo+i]*xy;
-
- ipo = ip;
-
- if(iv==0) {
-
- /* Generate white noise for unvoiced */
-
- for(i=0;i<ip;i++)
- /*exc[ORDER+i] = (int)(Rrandom() * 0.015625);*/
- exc[ORDER+i] = Rrandom() >>6;
-
- /* Impulse doublet excitation for plosives */
-
- px = ((Rrandom()+32768)*(ip-1)>>16) + ORDER + 1;
- /*pulse = PESCL*(ratio*.25)*342;*/
- pulse = ratio*85.5;
- if(pulse>2000) pulse = 2000;
- exc[px-1] += pulse;
- exc[px] -= pulse;
-
- /* Load voiced excitation */
- }
- else {
- /*sscale = sqrt((float)ip)/6.928;*/
- sscale = sqrt((float)ip)*0.144341801;
- for(i=0;i<ip;i++) {
- exc[ORDER+i] = 0.;
- if(i<=25) exc[ORDER+i] = sscale*kexc[i];
- lpi0 = exc[ORDER+i];
- exc[ORDER+i] = a0*exc[ORDER+i] + a1*lpi1 + a2*lpi2 /*+ a3*lpi3*/;
- /*lpi3 = lpi2;*/
- lpi2 = lpi1;
- lpi1 = lpi0;
- }
- for(i=0;i<ip;i++) {
- /*noise[ORDER+i] = MESCL * (int)(Rrandom() * 0.015625);*/
- noise[ORDER+i] = Rrandom() >>6;
- hpi0 = noise[ORDER+i];
- noise[ORDER+i] = b0*noise[ORDER+i] + b1*hpi1 + b2*hpi2 /*+ b3*hpi3*/;
- /*hpi3 = hpi2; */
- hpi2 = hpi1;
- hpi1 = hpi0;
- }
- for(i=0;i<ip;i++)
- exc[ORDER+i] += noise[ORDER+i];
-
- }
-
- /* Synthesis filters:
- * Modify the excitation with all-zero filter 1 + G*SUM */
-
- xssq = 0;
- for(i=0;i<ip;i++) {
- k = ORDER + i;
- sum = 0.;
- for(j=0;j<ORDER;j++)
- sum += coef[j]*exc[k-j-1];
- sum *= g2pass;
- exc2[k] = sum + exc[k];
- }
-
- /* Synthesize using the all pole filter 1 / (1 - SUM) */
-
- for(i=0;i<ip;i++) {
- k = ORDER + i;
- sum = 0.;
- for(j=0;j<ORDER;j++)
- sum += coef[j]*exc2[k-j-1];
- exc2[k] += sum;
- xssq = xssq + exc2[k]*exc2[k];
- }
-
- /* Save filter history for next epoch */
-
- for(i=0;i<ORDER;i++) {
- exc[i] = exc[ip+i];
- exc2[i] = exc2[ip+i];
- }
-
- /* Apply gain to match RMS */
-
- ssq = rms*rms*ip;
- gain = sqrt(ssq/xssq);
- for(i=0;i<ip;i++)
- sout[i] = gain*exc2[ORDER+i];
-
-
- }
-